<?php

declare(strict_types=1);
/**
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2023/5/25.
 */

namespace App\Console;

use App\Exceptions\CommonExceptionConstants;
use App\Exceptions\ServiceException;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;

abstract class Enum
{
    protected static $labelMaps = [];
    private static $constCacheArray;

    public static function getKeys(): Collection
    {
        return self::getConstants()->keys();
    }

    public static function getLowerKeys(): Collection
    {
        return self::getConstants()->keys()->map(function ($item) {
            return strtolower($item);
        });
    }

    public static function getValues(): Collection
    {
        return self::getConstants()->values();
    }

    public static function getKey($value): string
    {
        return self::getConstants()->search($value);
    }

    public static function getValue(string $key)
    {
        return self::getConstants()->get($key);
    }

    /**
     * 获取字段转译.
     *
     * @param $value
     *
     * @return string
     */
    public static function getDescription($value): string
    {
        $key = static::getLowerKey($value);
        $className = explode('\\', static::class);
        $className = strtolower(Str::snake(array_pop($className)));
        if ('common_exception_constants' === $className) {
            return __("exception.exception.{$key}");
        }

        return __("common.{$className}.{$key}");
    }

    public static function getLowerKey($value): string
    {
        return strtolower(self::getKey($value));
    }

    public static function getMaps(): array
    {
        $maps = [];
        foreach (self::getValues() as $value) {
            $maps[$value] = self::getDescription($value);
        }

        return $maps;
    }

    private static function getConstants(): Collection
    {
        if (null === self::$constCacheArray) {
            self::$constCacheArray = [];
        }

        $calledClass = static::class;

        if (!\array_key_exists($calledClass, self::$constCacheArray)) {
            try {
                $reflect = new \ReflectionClass($calledClass);
                self::$constCacheArray[$calledClass] = $reflect->getConstants();
            } catch (\ReflectionException $e) {
                throw new ServiceException(CommonExceptionConstants::ERROR_PARAM);
            }
        }

        return collect(self::$constCacheArray[$calledClass]);
    }
}
